        TITL DAI FIRMWARE 2E407-2E5FB  V1.1
        ORG   :E407
*
*
*
****************************
* SET UP SCREEN FOR MODE 0 *
****************************
*
* Sets up a mode 0 screen, whatever the current mode
* is. If already a character area exists, it is
* moved to the top of the new screen.
*
* Entry: None.
* Exit:  All registers corrupted.
*        CY=0: OK.
*        CY=1: No room.
*
SSM0    STC             CY=1
        PUSH  PSW
        LXI   H,:E030   Startaddr mode 0 table
        CALL  :E545     Load pointers with parameter
        JC    :E43C     If no room available
        LXI   D,:007C   Addr text colour table
        PUSH  D         Save addr
        LHLD  :0080     Get 1st byte screen RAM
        MVI   B,:06
        CALL  :E5FC     Set up header
        LDA   :009D     Get old screen mode
        CPI   :10       During initialisation ?
        JZ    :E42D     Then jump
        RAR             Split screen ?
        JNC   :E42D     Jump if not
        CALL  :E635     If split mode: move old
 REM text, cursor, etc
SS010   XCHG            Addr after header in DE
        LHLD  :008C     Get addr end char area
        XCHG
        CALL  :E1FD     Blank char area
        CNC   :E687     Set cursor at begin 1st line
 REM
* Entry from SSMG:
 REM
SS015   POP   D
        POP   PSW
        CMC             CY=0
        RET
 REM
* If no room available:
* Entry from SSMG, SSM, SSMA:
 REM
SS020   POP   PSW       CY=1
        RET
*
**********************************
* SET UP SCREEN FOR GRAPHIC MODE *
**********************************
*
* Entry: A:  Screen mode (split if odd).
* Exit:  CY=0: O.K.:
*        Split mode:       DE: Addr text colours.
*        All graphic mode: DE: Addr graph colours.
*        AF preserved. BCHL corrupted.
*        CY=1: Insufficient room.
*
SSMG    STC
        PUSH  PSW
        MOV   D,A       Screen mode in D
        ANI   :01       Z=1 if full colour mode
        MOV   A,D
        RAR             Disable split mode bit in A
        CNZ   :E4B6     If split mode: set up screen
        CZ    :E45F     If full colour mode: idem
        JC    :E43C     Abort if no room
        POP   PSW       Get mode code
        PUSH  PSW
        PUSH  D
        LXI   D,:009E   Addr COLORG table
        LHLD  :0080     Get addr 1st byte screen RAM
        MVI   B,:06     Depth each blanking line
 REM in header -1
        CALL  :E5FC     Set up header with COLORG
 REM colours
        JMP   :E438     Quit, all OK
*
* SET UP A FULL GRAPHIC SCREEN:
*
* Sets up a screen RAM for an all-graphics mode.
*
* Entry: A: Mode code /2.
*        D: Mode code.
* Exit:  CY=0: O.K.:
*              DE points to table graphic colours.
*              AF preserved. BCHL corrupted.
*        CY=1: Insufficient space.
*
SSM     STC
        PUSH  PSW
        LXI   H,:E59A   Addr table vectors full
 REM graphic mode
        CALL  :E539     Set up screen mode
        JC    :E43C     Jump if no room
        LDA   :009D     Get current screen mode
        SUB   D         ) Check if change split
        DCR   A         ) to all graphics
        JZ    :D700     Then check if sufficient
 REM RAM available and change
 REM mode
        CALL  :E36B     Delete cursor
        LDA   :0096     Get nr of graphics lines
        MOV   C,A       in C
        LHLD  :0082     Get addr top graph area
        CALL  :E5AD     Blank whole screen
SSM10   LXI   D,:009E   Addr COLORG table
        POP   PSW
        CMC             CY=0: O.K.
        RET
 REM
* Change from split to all-graphic mode:
 REM
SSM21   JNC   :D70F     Set up screen mode
        CALL  :E36B     Delete cursor
        LHLD  :0088     Get addr temp save area
        MOV   B,H       ) in BC
        MOV   C,L       )
        PUSH  B         Save it on stack
        LHLD  :0092     Get startaddr archive
 REM area
        XCHG            in DE
        LHLD  :008C     Get addr end archive area
        CALL  :E6C2     Move archive area into
 REM temp save area
        LHLD  :0086     Get addr top of rolled area
        MOV   B,H       ) in BC
        MOV   C,L       )
        LHLD  :0082     Get addr top old graphics
        XCHG            in DE
        LHLD  :0099     Get end old screen
        CALL  :E6C2     Move lower part screen
 REM downwards
        MOV   B,D       ) BC is addr where to put
        MOV   C,E       ) archive area
        POP   D         Get startaddr temp save area
        LHLD  :0090     Get end temp save area
        CALL  :E6C2     Move temp save area to
 REM top of screen
        JMP   :E47F     Quit
*
* SET UP SCREEN FOR SPLIT MODE:
*
* Sets up a split screen for a given mode in the
* lower RAM.
*
* Entry: A: Mode code /2.
*        D: Mode code.
* Exit:  CY=0: O.K.:
*              DE: Address text colour table.
*              AF preserved, BCHL corrupted.
*        CY=1: Insufficient space.
*
SSMA    STC
        PUSH  PSW
        LXI   H,:E5A0   Startaddr table vectors
 REM split modes
        CALL  :E539     Set up screen mode
        JC    :E43C     Abort if insufficient space
        LDA   :009D     Get old screen mode
        SUB   D         ) Check if change from
        INR   A         ) all-graph to split
        PUSH  PSW       Preserve flags
        PUSH  D         and new mode code
        JNZ   :E4F9     If not splitting old mode:
 REM clear graph and moved areas
        CALL  :D706     Check suff RAM available;
 REM prepare full graphic mode
        NOP
        JNC   :D70D     Set up current mode if
 REM not O.K.
        LHLD  :0092     Get start temp save area
        MOV   B,H       ) in BC
        MOV   C,L       )
        LHLD  :0082     Get addr after header
        XCHG            in DE
        LHLD  :0086     Get addr top of screen
        CALL  :E6C2     Move top of screen into
 REM temp save area
        MOV   B,D       ) BC is addr top of screen
        MOV   C,E       )
        XCHG            Addr top rolled up area
        LHLD  :0099     Get previous end of graphics
        CALL  :E6C2     Move lower part of screen
        LHLD  :008E     Get final place for archive
 REM code
        MOV   B,H       ) in BC
        MOV   C,L       )
        LHLD  :0092     Get addr start temp. save
 REM area
        XCHG            in DE
        LHLD  :0090     Get addr end split mode
        CALL  :E6C2     Move temp save area into
 REM archive area
SMA10   LHLD  :008A     Get start addr char area
        XCHG            in DE
        LHLD  :008C     Get addr end char area
        LDA   :009D     Get current screen mode
        RAR             Check mode
        MVI   C,:04     Nr of char lines in A-mode
        XCHG
        CNC   :E1FD     Blank char area
        CNC   :E687     Cursor on begin of line
        CC    :E635     Find old text and move it
        POP   D
        LHLD  :0082     Get addr after header
        LDA   :0097     Get nr saved graphics lines
        MOV   C,A       in C
        LDA   :0096     Get nr of graphics lines
        SUB   C         minus saved ones
        MOV   C,A       stored in C
        POP   PSW
        CNZ   :E5AD     Blank visible graph area
        LHLD  :008E     Get addr end of screen
        LDA   :0097     Get nr saved graphics lines
        MOV   C,A       in C
        CNZ   :E5AD     Blank saved graph area
        LXI   D,:007C   Addr text colour table
        MVI   B,:00     Middle as narrow as possible
        LHLD  :0088     Get addr middle area
        POP   PSW       Get mode code
        CALL  :E5FC     Set up middle area
 REM (blanking)
        CMC
        RET
*
* SET UP SCREEN FOR MODE:
*
* Selects the right table according to the mode
* number and sets the screen variables.
*
* Entry: A:  Mode code /2.
*        HL: Points to screen parameter vectors
*            for each pair of modes.
* Exit:  CY=0: O.K.:
*              AFHL corrupted, BCDE preserved.
*        CY=1: Insufficient space.
*
TABP    ANI   :0E       Bits 1,2,3 only
        CALL  :E701     Add offset to start table
        NOP
        NOP
        NOP
        MOV   A,M       )
        INX   H         ) Get addr from table in HL
        MOV   H,M       )
        MOV   L,A       )
*
* LOAD POINTERS WITH SCREEN PARAMETERS:
*
* Set up vector area 0084-0098 with variables
* describing the current state of the screen
* in the current mode.
*
VARS    STC
        PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        PUSH  H
        PUSH  H
        LHLD  :0080     Get addr 1st byte screen RAM
        MOV   B,H       in BC
        MOV   C,L
        POP   H         Get startaddr table
        MOV   A,C       )
        SUB   M         )
        MOV   E,A       ) Calc end area used in new
        INX   H         ) mode. Store it in DE.
        MOV   A,B       )
        SBB   M         )
        MOV   D,A       )
        LXI   H,:0000
        JC    :E560     Jump if insufficient space
        XCHG
VRS05   STC
        CALL  :E5A6     Make room for new mode
        JNC   :E596     Jump if no room available
        LHLD  :0088     Get old addr after end
 REM graphics area
        SHLD  :0099     and save it
        LHLD  :008A     Get old startaddr char area
        SHLD  :009B     and save it
 REM
* Set up area 0084-0093:
 REM
        LXI   D,:0084   Start of variables which
 REM need offsets
        MVI   L,:08     Nr of pointers to be set
VRS10   XTHL            Get addr screen parameters
        MOV   A,C
        SUB   M         Calc lobyte
        STAX  D         And store it in pointer
        INX   H         Next byte
        INX   D
        MOV   A,B
        SBB   M         Calc hibyte
        STAX  D         And store it in pointer
        INX   H
        INX   D
        XTHL
        DCR   L         Decr counter
        JNZ   :E578     Next parameter
 REM
* Set up area 0094-0098:
 REM
        POP   H         Get addr 1st parameter
        MVI   B,:05     Nr unadjusted constant bytes
VRS20   MOV   A,M       Get parameter
        STAX  D         and store it in pointer
        INX   H
        INX   D
        DCR   B         Decr counter
        JNZ   :E58B     Next parameter
        JMP   :E12E     Popall, CY=0, ret
 REM
* If no room available:
 REM
VRS30   POP   H
        JMP   :E138     Popall (CY=1), ret
*
* VECTORS TO TABLES SCREEN PARAMETERS:
*
* The startaddresses of the tables with para-
* meters for the graphic modes are given.
*
TABM    DBL   :E045     mode 1/2
        DBL   :E06F     mode 3/4
        DBL   :E099     mode 5/6
*
TABMA   DBL   :E05A     mode 1A/2A
        DBL   :E084     mode 3A/4A
        DBL   :E0AE     mode 5A/6A
*
*************************************
* PERFORM MEMORY MANAGEMENT ROUTINE *
*************************************
*
* Entry: HL points to last free byte in RAM.
*
SMKRM   INX   H
        PUSH  H
        LHLD  :00C4     Get addr mem.management
 REM routine
        XTHL            Put it on stack
        RET             Perform this routine and
 REM return afterwards to origin.
 REM returnaddress.
*
*********************************
* SET UP AN EMPTY GRAPHICS AREA *
*********************************
*
* Initialises an area of the screen into graphic
* state and blanks it. In 16-colour modes, all
* pixels are set 'on'. The foreground colour is
* the first COLORG colour, the background is black.
*
* Entry: D:  Mode code.
*        C:  Number of graphic lines (1-256).
*        HL: Start of area.
* Exit:  All registers preserved.
*
SGINIT  PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        MOV   A,D       Mode in A
        PUSH  H
        LXI   D,:0000   8 blobs 1st graph colour
        MVI   L,:00     Control byte: graph, low
 REM def, 4-colour
        RAR
        RAR
        JC    :E5CB     Jump if 4-colour mode
 REM
* 16-colour mode only:
 REM
        PUSH  PSW
        LDA   :009E     Get 1st colour
        ADD   A         )
        ADD   A         ) Move lonibble into
        ADD   A         ) hinibble
        ADD   A         )
        MOV   D,A       Result in D
        MVI   E,:FF     8 blobs foreground
        POP   PSW
        MVI   L,:80     Control byte: graph, low
 REM def, 16-colour
SGI10   RAR
        JC    :E5DE     Jump if mode 3/4
 REM
* Mode 1/2 and 5/6 only:
 REM
        RAR
        MVI   H,:0B     Low def fields/line
        MVI   A,:03     Low def bit mask
        JNC   :E5E2     Jump if mode 1/2
 REM
* Mode 5/6 only:
 REM
        MVI   H,:2C     Super def fields/line
        MVI   A,:20     Super def bit mask
        JMP   :E5E2
 REM
* Mode 3/4 only:
 REM
SGI20   MVI   H,:16     High def fields/line
        MVI   A,:11     High def bit mask
*
SGI30   ORA   L         Add def bits to get mode
 REM code
        MOV   B,A
        MOV   A,H       Line length in A
        POP   H         Get top of area
SGI50   PUSH  PSW       Save line length
        MOV   M,B       Load line control byte
        DCX   H
        MVI   M,:40     Null line colour byte
        DCX   H
SGI60   MOV   M,E       ) Load screen data locations
        DCX   H         ) with 1 blank field
        MOV   M,D       )
        DCX   H
        DCR   A         Next screen location
        JNZ   :E5EC     Jump if line not ready
        POP   PSW       Restore nr of locations in A
        DCR   C         Next screen line
        JNZ   :E5E6     Jump if not ready
        JMP   :E138     Popall, ret
*
*
*
        END
